<?php
// Linux Counter special functions including database access

// Stuff that needs to be done by all Counter pages
$homedir = getenv("COUNTER_ROOT");
// Set defaults
$dbname = "counter";
$dbhost = "database";
$maintenance = 0;
chdir($homedir);
readinitfile();
if ($homedir != getenv("COUNTER_ROOT")) {
   print("MISCONFIGURATION: Homedir $homedir, COUNTER_ROOT " . getenv("COUNTER_ROOT") . "\n");
   exit(1);
}

session_start();

# Set up default menu

$counter_site = "http://" . $website;
$secure_counter_site = "https://" . $website;

$menu["Home"] = array("Home", "$counter_site/");
$menu["Login"] = array("Login", "$counter_site/person/login.php?url=/person/");
$menu["News"] = array("News", "$counter_site/news.php");
$menu["Statistics"] = array("Statistics", "$counter_site/reports/");
$menu["Project"] = array("Project info", "$counter_site/organization/");
$menu["Admin"] = array("Admin", "$secure_counter_site/adm/");
$menu["Help"] = array("Help", "$counter_site/help.php", "right");
$menu["Homepage"] = array("Homepage", "$counter_site/person/");
$menu[""] = array("", "/");
$menu[""] = array("", "/");

if ($maintenance == 0) {
requirefiles("database");
}
requirefiles("functions");

function requirefiles($name) {
   require "$name.php";
}			    


function readinitfile() {
   # Global variables that can be set by this function
   global $dbname;
   global $dbhost;
   global $homedir;
   global $website;
   global $maintenance;
  
   $initfile = file(".counter.ini");
   while (list ($lineno, $line) = each($initfile)) {
	$line = trim($line);
	# PHP advantage:
	# only the global()ed vars above will have effect outside the routine
	if (preg_match("/^(\S+)=(.*)/", $line, $matches)) {
	    $$matches[1] = $matches[2];
        }
   }
}


function pagestart() {
// Emit the DOCTYPE declaration when the file is included.
// I want to change this, so keep it in the common file...
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<?
}

// Strictly layout element stuff
// control para is "head" if the page has its own HEAD directives

function pagehead($title, $control="all") {
   if ($control == "all") { echo "<head>"; }
// note: according to XHTML, link should end with />, but W3C validator flags it as error
?>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<link rel="stylesheet" type="text/css" href="/css/home.css">
<link rel="alternate" type="application/rss+xml" title="Linux Counter News RSS" href="http://counter.li.org/linuxcounternews.rss">
<title>Linux Counter: <?php echo $title ?></title>
<?php
   if ($control == "all") { echo "</head>"; }
}

function pagetop($title="", $image="/gifs/Logo-small.png") {
   global $menu;
   global $counter;
   global $maintenance;

   $login = $counter->get_input("login", "", "cookie");
   $adminuser = $counter->get_input("adminuser", "", "cookie");

   $REMOTE_USER = getenv("REMOTE_USER");

?>
<div class="menu">
<table class="menu">
  <tr>

<?php
   if ($REMOTE_USER || $adminuser) {
      if (!$login) {
          $list = array("Home", "Login", "News", "Statistics",
            "Project", "Admin", "Help");
      } else {
          $list = array("Home", "Homepage", "News", "Statistics",
            "Project", "Admin", "Help");
      }

   } else if ($login) {
      $list = array("Home", "Homepage", "News", "Statistics",
       "Project", "Help");

   } else {
      $list = array("Home", "Login", "News", "Statistics",
       "Project", "Help");
   }
   foreach ($list as $item) {
      $widthsum += strlen($menu[$item][0]) + 2; # ROUGH estimate of width
   }
   $widthsum -= 2;
   foreach ($list as $item) {
      $widths[$item] = intval((strlen($menu[$item][0]) + 2) * 100 / $widthsum);
   }
   
   foreach ($list as $item) {
      print "<td width=\"";
      print $widths[$item] . "%\"";
      if ($maintenance == 1) {
	  if ($menu[$item][2]) { print " align=\"". $menu[$item][2] . "\""; }
	      print " class=\"menu\">";
	      print $menu[$item][0] . "</td>\n";
      } else {
          if ($menu[$item][2]) { print " align=\"". $menu[$item][2] . "\""; }
              print " class=\"menu\"><a class=\"head\" href=\"";
              print $menu[$item][1];
              print "\" target=\"_top\">" . $menu[$item][0] . "</a></td>\n";
      }
   }
?>
</table>
</div>
<?php
print "<div class=\"midsec\">\n";
if ($maintenance == 1) {
   include "maintenance.php";
   exit;
} else {
   if ($title != "") {
      echo "<h1><img src=\"$image\" alt=\"Linux Counter Logo\" />\n$title</h1>\n";
   }
}
}

function pagebottom($w3valid="") {

   global $counter;
   $login = $counter->get_input("login", "", "cookie");
   $webmaster_email = emailCloaking("Webmaster@counter.li.org")

?>
<p>
<?php if ($login) { ?>
You are logged in as user #<?php echo currentuser() ?></p>
<?php } ?>
</div>
<div class="footer">
<table class="footer">
<tr><td align="left" valign="middle">
Contact: <?php print $webmaster_email ?>
</td>
<td align="right" valign="middle">

<?php if ($w3valid == "yes") { ?>
<a href="http://validator.w3.org/check?uri=referer" target="_blank">
<img src="http://www.w3.org/Icons/valid-html401" alt="Valid HTML 4.01 Transitional" height="31" width="88" border="0" /></a>
<?php } else {} ?>

</td></tr>
</table>
</div>
<br />
<?php
}

# set me as a showpage
function iamashowpage() {
   $HTTP_HOST = getenv("HTTP_HOST");
   $REQUEST_URI = getenv("REQUEST_URI");
   if (getenv("HTTPS") == "on") {
       $selfurl = "https://" . $HTTP_HOST . $REQUEST_URI;
   } else {
       $selfurl = "http://" . $HTTP_HOST . $REQUEST_URI;
   }
   if ($_SESSION[showpage] != $selfurl) {
      $_SESSION[showpage] = $selfurl;
      clearmessage();
   }
}

function showmessage() {
   $message = $_SESSION[message];
   if ($message) {
      print "<p><font color=\"red\" size=+2 align=\"center\">";
      print $message;
      print "</font></p>\n";
      # Clean SESSION[message] after showing, otherwise it will pop up
      # at another screen
      #$_SESSION[message] = "";
   }
}

function clearmessage() {
   $_SESSION[message] = '';
}


//--------------- COUNTER DATABASE ACCESS FUNCTIONS -------------------------


// Fetch Raw or Clean fields from the Text elements of a record
function xfields($table, $key, $style) {
    $query = mysql_query("select f_$style from $table where f_key = $key");
    if (!$query) {
       print("MySQL error: " . mysql_errno() . ":" . mysql_error() . "<br>");
       die("Query for $style $key from $table failed");
    }
	
    $arr = mysql_fetch_row($query);
    $raw = $arr[0];
    $tempfields = preg_split("/\n/", $raw);
    while ($f = each($tempfields)) {
        if (preg_match("/^([-a-z0-9A-Z_]+):(.*)/", $f[1], $ff)) {
            $fields[$ff[1]] = $ff[2];
        }
    }
    return $fields;
}

function rawfields($table, $key) {
    return xfields($table, $key, "raw");
}

function cleanfields($table, $key) {
    return xfields($table, $key, "clean");
}

function recage($table, $key) {
// Because PHP doesn't do this natively, use MySQL for calculating record age.
// This is silly.
    $query = mysql_query("select to_days(now()) - to_days(f_mtime) as recage from $table where f_key = $key");
    if ($query == 0) {
       print("MySQL error: " . mysql_errno() . ":" . mysql_error() . "<br>");
       die("Query for recage failed");
    }	
    $arr = mysql_fetch_row($query);
    return $arr[0];
}

// Fetch email addresses from email table
function emailfields($table, $key, $style) {
    $query = mysql_query("select f_$style from $table where owner = $key");
    if (!$query) {
       print("MySQL error: " . mysql_errno() . ":" . mysql_error() . "<br>");
       die("Query for $style $key from $table failed");
    }

    $index=0;
    while ($arr = mysql_fetch_array($query)) {
       $email[$index] = $arr[0];
       ++ $index;
    }
    return $email;
}

// Fetch public email addresses from email table
function pemailfields($table, $key, $style) {
    $query = mysql_query("select f_$style from $table where owner = $key and may_publish = 'YES'");
    if (!$query) {
        print("MySQL error: " . mysql_errno() . ":" . mysql_error() . "<br>");
        die("Query for $style $key from $table failed");
    }

    $index=0;
    while ($arr = mysql_fetch_array($query)) {
        $email[$index] = $arr[0];
        ++ $index;
    }
    return $email;
}

class User {
    var $userid;
    var $ufields;
    var $pfields;
    var $recage;
    var $efields;
    var $pefields;

    function User($userid = "not-given") {
	if ($userid == "not-given") {
	    $this->userid = currentuser();
        } else {
	    $this->userid = $userid;
        }
	$this->ufields = rawfields("users", $this->userid);
	$this->pfields = rawfields("persons", $this->userid);
        $this->pcfields = cleanfields("persons", $this->userid);
        $this->recage = recage("users", $this->userid);
    }

    function create($userid = "not-given") {
      if ($userid == "not-given") {
	$userid = currentuser();
      }
      if (!(int)$userid) {
	trigger_error("Wrong data type for userid");
	return null;
      }
      return new User($userid);
    }

    function privacy() {
	if ($this->ufields[privacy]) {
	    return $this->ufields[privacy];
        } elseif (preg_match("/y(es)?/i", $this->pcfields["may_publish"])) {
	    return "name";
        } elseif (preg_match("/y(es)?/i", $this->pcfields["may-publish"])) {
	    return "name";
        } else {
	    return "none";
        }
    }

    function hasperson() {
        if ($this->pfields["f_ctime"]) {
	    return 1;
        } else {
            return 0;
        }
    }

    function get_email_addresses() {
        $this->efields = emailfields("email", $this->userid, "key");
        return $this->efields;
    } 

    function get_public_email_addresses() {
        $this->pefields = pemailfields("email", $this->userid, "key");
        return $this->pefields;
    }
}

function placelist($type, $checkvalue, $within) {
// Create a list of place IDs from the places database for use within a
// SELECT statement.
// Returns the name ID for the currently selected entry, so that this can be
// used for the selection at next level. (Not completely optimal)

    if (!$within) {
	$query = mysql_query("select name, longname, f_key from places
                                     where places.type = '$type'
				     order by longname");
    } else {
	$query = mysql_query("select places.name, places.longname, places.f_key
                                     from places
                                     where places.type = '$type'
				     and places.within = $within
				     order by longname");
	
    }
    while ($arr = mysql_fetch_row($query)) {
        echo "<option";
        if (preg_match(preg_quote("/$arr[0]/i"), $checkvalue)) {
	    echo " selected";
	    $found = 1;
	    $nextlevel = $arr[2];
	}
        echo " value=\"$arr[0]\">$arr[1]</option>\n";
    }
    if (!$found) {
	echo "<option value=\"$checkvalue\" selected>$checkvalue (unlisted)</option>\n";
        $nextlevel = "";
    }
    return $nextlevel;
}	    


function personid($key) {

   global $counter;
 
   $login = $counter->get_input("login", "", "cookie");

	$pers = mysql_query("select name, email from persons where f_key = $key");
	if (mysql_num_rows($pers) == 0) {
		return $key . " (not listed in database)";
	}
	$parr = mysql_fetch_array($pers);
	if ( $login ) {	
		return person_url($key, $parr[name]) . " &lt;" . emailCloaking($parr[email],0) . "&gt;";
	} else {
		return person_url($key, $parr[name]);
	}
 }

// return an URL pointing to this place
// ugly: it hardcodes the URL of the "place.php" script.
 function placeurl($name, $longname) {
       $placeurl = urlencode($name);
       return "<a href=\"/reports/place.php?place=$placeurl\">$longname</a>";
 }


// return a pointer to the place.php page, focusing on a place
function place_page($name, $longname) {
       $placeurl = urlencode($name);
       return "<a href=\"/reports/place.php?place=$placeurl\">$longname</a>";
}

 function place_bar($place, $print_type = 0 ) {
	if ( $place[within] == 0 ) {
		print placeurl($place[name], $place[longname]);
		return;
	}
	$placeq = mysql_query("select f_key, name, longname, within, type from places
			where  f_key = '$place[within]'");
	$nplace = mysql_fetch_array($placeq);
	if ( $place[type] == "alias" ) {   
		place_bar($nplace, 1);
	} else {
		place_bar($nplace);
	}
	if ( $place[type] == "alias" ) {
		return;
	}
	print " > ".placeurl($place[name], $place[longname]);
	if ($print_type) {
		print "&nbsp;&nbsp;($place[type])";
	}
	return;
  }

 function findmaintainer($place) {

	$suffix = "";
	while ($place[maintainer] == 0 && $place[within] <> 0) {
		$placeq = mysql_query("select f_key, longname, within, maintainer from places where f_key = '$place[within]'");
 		$place = mysql_fetch_array($placeq);
		$suffix = " (for " . $place[longname] . ")";
       	}
	$thisplace = cleanfields('places', $place[f_key]);
	if ( $thisplace[maintainer] == $place[maintainer] ) {
		$ret =  personid($place[maintainer]) . $suffix;
	} else {
		$maint = split(" ", $thisplace[maintainer]);
		$x = 0;
		while ( $maint[$x] != "" ) {
			if ($x > 0 ) {
				$ret .= "<br>";
			}
			$ret = $ret.personid($maint[$x++]) . $suffix;
		}
	}
	// change the @ in email addresses to their hex counterpart
	$ret =  preg_replace("/@/","&#x40;",$ret);
	return $ret;
 }

function person_url($key, $name) {
        global $counter_site;
	if ( $name == "" ) {
		$name = "Anonymous";
	}
	return "<a href=\"$counter_site/cgi-bin/runscript/display-person.cgi?".
		"user=$key\">$name</a>";  
}

/**
* simple Javascript Cloaking
* email cloacking
* by default replaces an email with a mailto link with email cloacked
*/
function emailCloaking( $mail, $mailto=1, $text='', $email=1 ) {
       // convert text
       $mail           = encoding_converter( $mail );
       // split email by @ symbol
       $mail           = explode( '@', $mail );
       $mail_parts     = explode( '.', $mail[1] );
       // random number
       $rand   = rand( 1, 100000 );

       $replacement    = "\n<script language='JavaScript' type='text/javascript'> \n";
       $replacement    .= "<!-- \n";
       $replacement    .= "var prefix = '&#109;a' + 'i&#108;' + '&#116;o'; \n";
       $replacement    .= "var path = 'hr' + 'ef' + '='; \n";
       $replacement    .= "var addy". $rand ." = '". @$mail[0] ."' + '&#64;' + '". implode( "' + '&#46;' + '", $mail_parts ) ."'; \n";
       if ( $mailto ) {
               // special handling when mail text is different from mail addy
               if ( $text ) {
                       if ( $email ) {
                               // convert text
                               $text   = encoding_converter( $text );
                               // split email by @ symbol
                               $text   = explode( '@', $text );
                               $text_parts     = explode( '.', $text[1]);
                               $replacement    .= "var addy_text". $rand ." = '". @$text[0] ."' + '&#64;' + '". implode( "' + '&#46;' + '", @$text_parts ) ."'; \n";
                        } else {
                                $text   = encoding_converter( $text );
                                $replacement    .= "var addy_text". $rand ." = '". $text ."';\n";
                        }
                        $replacement    .= "document.write( '<a ' + path + '\'' + prefix + ':' + addy". $rand ." + '\'>' ); \n";
                        $replacement    .= "document.write( addy_text". $rand ." ); \n";
                        $replacement    .= "document.write( '<\/a>' ); \n";
                } else {
                        $replacement    .= "document.write( '<a ' + path + '\'' + prefix + ':' + addy". $rand ." + '\'>' ); \n";
                        $replacement    .= "document.write( addy". $rand ." ); \n";
                        $replacement    .= "document.write( '<\/a>' ); \n";
               }
        } else {
                $replacement    .= "document.write( addy". $rand ." ); \n";
        }
        $replacement    .= "//--> \n";
        $replacement    .= "</script> \n";
        $replacement    .= "<noscript> \n";
        $replacement    .= " -- Email address protected against harvesting -- ";
        $replacement    .= "\n</noscript> \n";

        return $replacement;
}

function encoding_converter( $text ) {
        // replace vowels with character encoding
        $text   = str_replace( 'a', '&#97;', $text );
        $text   = str_replace( 'e', '&#101;', $text );
        $text   = str_replace( 'i', '&#105;', $text );
        $text   = str_replace( 'o', '&#111;', $text );
        $text   = str_replace( 'u', '&#117;', $text );

        return $text;
}

/* Added by Paul Nicholson - paul&#x40;webpowerdesign.net */
class counter_drv {
    var $filters       = array(
                               'number'          => '/^([0-9]+)$/',
                               'char'            => '/^([A-Z])$/i',
                               'alpha'           => '/^([\_\-A-Za-z]+)$/',
                               'alphanum'        => '/^([A-Z\-a-z\_0-9]+)$/',
                               'area'            => '/^([A-Z]{2}[^;]*)$/',
                               'place'           => '/^([0-9A-Za-z\\\'\:\\\\ ().-]+)$/'
# to allow singlequote in place, have to escape the backslash in front of it.
# php backslashes it too, so I have to allow backslash, which requires
# FOUR backslashes in a row.
                              );

    /* Function get_input(string $id, string $filter_type, string $method="")
    *  Pulls data out of 'method' superglobal and check it using 'filter_type'.
    *  $method can be one method(get,post,cookies) or can be multiple
    *    methods(get,post,cookies) separated by the "|" symbol. Preferring the first
    *    method that returns data in the order passed.
    *  If no method is passed function will check the data in $id for validity.
    */
    function get_input($id, $filter_type, $method="") {
        if(($filter_type) && (!isset($this->filters[strtolower($filter_type)]))) { return FALSE; }
        if(is_array($method)) {
            if(!$filter_type) { return $method[$id]; }
            if(preg_match($this->filters[strtolower($filter_type)], $method[$id])) {
                return $method[$id];
            } else {
                return FALSE;
            }
        }
        $method = explode("|", $method);
        foreach($method as $v) {
            switch (strtolower($v)) {
                case 'get':
                     if(!$filter_type) { return $_GET[$id]; }
                     if(preg_match($this->filters[strtolower($filter_type)], $_GET[$id])) {
                         return $_GET[$id];
                     } else {
                         return FALSE;
                     }
                     break;
                case 'post':
                     if(!$filter_type) { return $_POST[$id]; }
                     if(preg_match($this->filters[strtolower($filter_type)], $_POST[$id])) {
                         return $_POST[$id];
                     } else {
                         return FALSE;
                     }
                     break;
                case 'session':
                     if(!$filter_type) { return $_SESSION[$id]; }
                     if(preg_match($this->filters[strtolower($filter_type)], $_SESSION[$id])) {
                         return $_SESSION[$id];
                     } else {
                         return FALSE;
                     }
                     break;
                case 'cookie':
                     if(!$filter_type) { return $_COOKIE[$id]; }
                     if(preg_match($this->filters[strtolower($filter_type)], $_COOKIE[$id])) {
                         return $_COOKIE[$id];
                     } else {
                         return FALSE;
                     }
                     break;
                default:
                     if(preg_match($this->filters[strtolower($filter_type)], $id)) {
                         return $id;
                     } else {
                         return FALSE;
                     }
                     break;
            }
        }
    }
    function add_filter($filter_name, $filter_regex) {
        if($this->filters[strtolower($filter_name)]){
            return FALSE;
        } else {
            $this->filters[strtolower($filter_name)] = $filter_regex;
            return TRUE;
        }
    }
}
$counter = new counter_drv;
?>
